<!-- @format -->

<template>
  <div>
    <transition name="m-message-fade">
      <div
        v-if="visible"
        :class="['m-message', `m-message--${type}`, customClass]"
        :style="[customStyle]"
        @mouseenter="clearTimer"
        @mouseleave="startTimer"
      >
        <div class="m-message__icon-container">
          <div class="m-message__icon-wrapper">
            <el-icon
              :class="`m-message__icon-wrapper--${type}`"
              class="animate-pulse"
              ><SuccessFilled v-if="type === 'success'" />
              <CircleCloseFilled v-if="type === 'error'" />
              <WarningFilled v-if="type === 'warning'" />
              <WarnTriangleFilled v-if="type === 'info'" />
            </el-icon>
          </div>
        </div>
        <div class="m-message__content">
          <span class="m-message__text">{{ message }}</span>
        </div>

        <div v-if="showClose" class="m-message__close" @click="close">❌</div>
      </div>
    </transition>
  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
  import {
    SuccessFilled,
    CircleCloseFilled,
    WarningFilled,
    WarnTriangleFilled,
  } from '@element-plus/icons-vue';

  interface MessageProps {
    id?: string;
    message?: string;
    type?: 'success' | 'warning' | 'error' | 'info';
    duration?: number;
    showClose?: boolean;
    onClose?: () => void;
    customClass?: string;
    customStyle?: object;
  }

  const props = withDefaults(defineProps<MessageProps>(), {
    id: '',
    message: '',
    type: 'info',
    duration: 3000,
    showClose: false,
    onClose: () => {},
    customClass: '',
    customStyle: () => ({}),
  });

  const visible = ref(false);
  const timer = ref<number | null>(null);

  const iconClass = computed(() => {
    const typeMap = {
      success: 'el-icon-success',
      warning: 'el-icon-warning',
      error: 'el-icon-error',
      info: 'el-icon-info',
    };
    return typeMap[props.type];
  });

  const close = () => {
    visible.value = false;
    if (props.onClose) {
      props.onClose();
    }
  };

  const clearTimer = () => {
    if (timer.value) {
      clearTimeout(timer.value);
      timer.value = null;
    }
  };

  const startTimer = () => {
    if (props.duration > 0) {
      timer.value = window.setTimeout(() => {
        close();
      }, props.duration);
    }
  };

  onMounted(() => {
    visible.value = true;
    startTimer();
  });

  onBeforeUnmount(() => {
    clearTimer();
  });

  defineExpose({
    close,
  });
</script>

<style lang="scss" scoped>
  .m-message {
    position: fixed;
    left: 50%;
    top: 40%;
    transform: translate(-50%, -50%);
    width: 80%;
    max-width: 300px;
    padding: 16px;
    border-radius: 12px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    background-color: #fff;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;

    &__icon-container {
      margin-bottom: 12px;
      width: 100%;
      display: flex;
      justify-content: center;
    }

    &__icon-wrapper {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      //   animation:
      //     spin 0.6s ease-in-out,
      //     scale-in 0.3s ease-out;
      //   i {
      font-size: 32px;
      animation: bounce 0.5s ease 0.3s both;
      &.animate-pulse {
        animation:
          bounce 0.5s ease 0.3s both,
          animate-pulse 1.5s infinite ease-in-out;
      }
      //   }

      &--success {
        // background-color: rgba(103, 194, 58, 0.1);
        color: #75c23a;
        width: 60px;
        height: 60px;
      }

      &--warning {
        // background-color: rgba(230, 162, 60, 0.1);
        // i {
        color: #e6a23c;
        width: 60px;
        height: 60px;
      }

      &--error {
        // background-color: rgba(245, 108, 108, 0.1);
        // i {
        color: #f56c6c;
        // }
        width: 60px;
        height: 60px;
      }

      &--info {
        // background-color: rgba(144, 147, 153, 0.1);
        // i {
        color: #909399;
        width: 60px;
        height: 60px;
        // }
      }
    }

    &__content {
      width: 100%;
      margin-bottom: 8px;
    }

    &__text {
      font-size: 16px;
      line-height: 1.5;
      color: #333;
      font-weight: 500;
    }

    &__close {
      position: absolute;
      top: 8px;
      right: 8px;
      font-size: 16px;
      color: #999;
      cursor: pointer;
      &:hover {
        color: #666;
      }
    }

    &--success {
      border-top: 3px solid #67c23a;
      //   box-shadow: 0 4px 20px rgba(#67c23a, 0.2);
      //   animation: success-glow 2s infinite alternate;
    }

    &--warning {
      border-top: 3px solid #e6a23c;
    }

    &--error {
      border-top: 3px solid #f56c6c;
    }

    &--info {
      border-top: 3px solid #909399;
    }
  }

  @keyframes spin {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(720deg);
    }
  }

  @keyframes bounce {
    0%,
    20%,
    50%,
    80%,
    100% {
      transform: translateY(0);
    }
    40% {
      transform: translateY(-10px);
    }
    60% {
      transform: translateY(-5px);
    }
  }

  @keyframes scale-in {
    0% {
      transform: scale(0);
      opacity: 0;
    }
    70% {
      transform: scale(1.1);
      opacity: 1;
    }
    100% {
      transform: scale(1);
      opacity: 1;
    }
  }

  @keyframes animate-pulse {
    0%,
    100% {
      opacity: 1;
      transform: scale(1);
    }
    50% {
      opacity: 0.8;
      transform: scale(1.15);
    }
  }

  @keyframes success-glow {
    from {
      box-shadow: 0 4px 20px rgba(103, 194, 58, 0.2);
    }
    to {
      box-shadow: 0 4px 25px rgba(103, 194, 58, 0.4);
    }
  }

  .m-message-fade-enter-active,
  .m-message-fade-leave-active {
    transition:
      opacity 0.4s,
      transform 0.4s;
  }

  .m-message-fade-enter-from,
  .m-message-fade-leave-to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.8);
  }
</style>
